package com.pricl.frame.core.service;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.List;

import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;

import com.github.miemiedev.mybatis.paginator.domain.PageList;
import com.pricl.frame.core.dao.mybatis.MyBatisMapperDao;
import com.pricl.frame.query.criteria.BaseCriteria;

@Transactional
public class BaseService<Entity, Criteria extends BaseCriteria, PK extends Serializable> implements Serializable {

	private static final long serialVersionUID = 8461480467399609713L;

	private static final Logger logger = LoggerFactory.getLogger(BaseService.class.getClass());

	@Autowired
	protected MyBatisMapperDao<Entity, Criteria, PK> myBatisMapperDao;

	protected Class<Entity> entityClass;

	@SuppressWarnings({ "unchecked", "rawtypes" })
	public BaseService() {
		try {
			Object genericClz = getClass().getGenericSuperclass();
			if ((genericClz instanceof ParameterizedType)) {
				this.entityClass = ((Class) ((ParameterizedType) genericClz).getActualTypeArguments()[0]);
			}
			logger.info("entityClass{}", this.entityClass.getName());
		} catch (RuntimeException e) {
			logger.error("entityClass{}", this.entityClass.getName());
		}
	}

	/**
	 * <p>
	 * 统计有多少条记录
	 * </p>
	 * 
	 * @param criteria
	 * @return
	 */
	@Transactional(readOnly = true)
	public int countByEntity(Criteria criteria) {
		return this.myBatisMapperDao.countByEntity(criteria);
	}

	/**
	 * <p>
	 * 根据id删除
	 * </p>
	 * 
	 * @param id
	 * @return
	 */
	public int deleteByPrimaryKey(PK id) {
		Entity record = this.myBatisMapperDao.selectByPrimaryKey(id);
		if (record != null) {
			return this.myBatisMapperDao.deleteByPrimaryKey(id);
		}
		return 0;
	}

	/**
	 * <p>
	 * 插入
	 * </p>
	 * 
	 * @param record
	 * @return
	 * @throws MySQLIntegrityConstraintViolationException 
	 */
	public int insert(Entity record)  {
		int count = this.myBatisMapperDao.insert(record).intValue();
		return count;
	}

	/**
	 * <p>
	 * 分页查询
	 * </p>
	 * 
	 * @param criteria
	 * @param rowBounds
	 * @return
	 */
	@Transactional(readOnly = true)
	public PageList<Entity> selectByEntityWithRowbounds(Criteria criteria, RowBounds rowBounds) {
		List<Entity> list = this.myBatisMapperDao.selectByEntityWithRowbounds(criteria, rowBounds);
		if ((list != null) && ((list instanceof PageList))) {
			PageList<Entity> pageList = (PageList<Entity>) list;
			return pageList;
		}
		return null;
	}

	/**
	 * <p>
	 * 根据criteria查询
	 * </p>
	 * 
	 * @param criteria
	 * @return
	 */
	@Transactional(readOnly = true)
	public List<Entity> selectByEntity(Criteria criteria) {
		return this.myBatisMapperDao.selectByEntity(criteria);
	}

	/**
	 * <p>
	 * 根据id查询
	 * </p>
	 * 
	 * @param id
	 * @return
	 */
	@Transactional(readOnly = true)
	public Entity selectByPrimaryKey(PK id) {
		return this.myBatisMapperDao.selectByPrimaryKey(id);
	}

	/**
	 * <p>
	 * 更新
	 * </p>
	 * 
	 * @param paramPK
	 * @param record
	 * @return
	 */
	public int updateByPrimaryKey(Entity record) {
		if (record != null) {
			return this.myBatisMapperDao.updateByPrimaryKey(record);
		}
		return 0;
	}
}